#include "RobotUser.h"
#include "LogEx.h"
#include "GameSession.h"
using namespace std;
using namespace SGLib;
SINGLETON_CLASS_INIT(CRobotUserManager);

void CRobotUserManager::Init()
{
    m_id = 1;
}

bool CRobotUserManager::HasRobot(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    return (it != m_robots.end());
}

void CRobotUserManager::CreateRobot(const std::string &account, const std::string &passwd, s32 recharge)
{
    GameData *data = new GameData();
    data->id = m_id++;
    data->account = account;
    data->passwd = passwd;
    data->state = E_State_Login;
    data->recharge = recharge;

    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it == m_robots.end() )
    {
        m_robots[ account ] = data;
        m_robotsIdx[ data->id ] = account;
        LOG_INFO( "[%s] account[%s] id[%llu] passwd[%s] create recharge[%ld]", __FUNCTION__,
            account.c_str(), data->id, passwd.c_str(), recharge );
    }
    else
    {
        LOG_ERROR( "[%s] account[%s] aleardy exist", __FUNCTION__, account.c_str() );
    }
}

void CRobotUserManager::DestoryRobot(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() )
    {
        int flag = 0;
        u64 id = 0;
        if( it->second )
        {
            id = it->second->id;
            flag = 1;
            delete it->second;
        }
        m_robots.erase( it );
        m_robotsIdx.erase( m_robotsIdx.find(id) );
        LOG_INFO( "[%s] account[%s] flag[%d]", __FUNCTION__, account.c_str(), flag );
    }
    else
    {
        LOG_ERROR( "[%s] account[%s] not found", __FUNCTION__, account.c_str() );
    }
}

void CRobotUserManager::UpdateRobot(const std::string &account, s32 recharge)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        LOG_INFO( "[%s] account[%s] old recharge[%lld] add[%d]", __FUNCTION__,
            account.c_str(), it->second->recharge, recharge );
        it->second->recharge += recharge;
    }
    else
    {
        LOG_ERROR( "[%s] account[%s] not found", __FUNCTION__, account.c_str() );
    }
}

void CRobotUserManager::UpdateRobot(const std::string &account, u64 userid, const std::string &sessionid)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        LOG_INFO( "[%s] account[%s] userid[%llu] sid[%s]", __FUNCTION__,
            account.c_str(), userid, sessionid.c_str() );
        it->second->userid = userid;
        it->second->sessionid = sessionid;
        it->second->state = E_State_GetServerList;
    }
    else
    {
        LOG_ERROR( "[%s] account[%s] not found", __FUNCTION__, account.c_str() );
    }
}

void CRobotUserManager::UpdateRobot(const std::string &account, u64 roleid, const std::string &ip, s32 port)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        LOG_INFO( "[%s] account[%s] roleid[%llu] addr[%s:%d]", __FUNCTION__,
            account.c_str(), roleid, ip.c_str(), port );
        it->second->roleid = roleid;
        it->second->ip = ip;
        it->second->port = port;
        it->second->state = E_State_EnterGame;
    }
    else
    {
        LOG_ERROR( "[%s] account[%s] not found", __FUNCTION__, account.c_str() );
    }
}

void CRobotUserManager::UpdateRobot(const std::string &account, void *session)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        LOG_INFO( "[%s] account[%s]", __FUNCTION__, account.c_str() );
        it->second->session = session;
        it->second->state = E_State_InGame;
    }
    else
    {
        LOG_ERROR( "[%s] account[%s] not found", __FUNCTION__, account.c_str() );
    }
}

u64 CRobotUserManager::GetId(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->id;
    }
    return 0;
}

const char* CRobotUserManager::GetPasswd(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        GameData *data = it->second;
        return data->passwd.c_str();
    }
    return NULL;
}

u64 CRobotUserManager::GetUserId(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->userid;
    }
    return 0;
}

const char* CRobotUserManager::GetSessionId(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->sessionid.c_str();
    }
    return NULL;
}

const char* CRobotUserManager::GetIp(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->ip.c_str();
    }
    return NULL;
}

s32 CRobotUserManager::GetPort(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->port;
    }
    return 0;
}

s32 CRobotUserManager::GetState(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->state;
    }
    return 0;
}

s64 CRobotUserManager::GetRecharge(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->recharge;
    }
    return 0;
}

s64 CRobotUserManager::GetRoleId(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->roleid;
    }
    return 0;
}

const char* CRobotUserManager::GetAccount(u64 id)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<u64, std::string>::iterator it = m_robotsIdx.find( id );
    if( it != m_robotsIdx.end() )
    {
        return it->second.c_str();
    }
    return NULL;
}

void* CRobotUserManager::GetSession(const std::string &account)
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.find( account );
    if( it != m_robots.end() && it->second )
    {
        return it->second->session;
    }
    return NULL;
}

void CRobotUserManager::RobotsHeartBeat()
{
    CGuardLock<CLock> g( m_Lock );
    std::map<std::string, GameData*>::iterator it = m_robots.begin();
    for( ; it != m_robots.end(); ++it )
    {
        if( !(it->second) ) continue;
        CGameSocket *s = (CGameSocket*)it->second->session;
        if( s )
        {
            s->HeartBeat();
        }
    }
}



